package com.sprouting.metadata.view.service;

import com.sprouting.metadata.core.model.TableModel;
import com.sprouting.metadata.core.utils.FileTool;
import com.sprouting.metadata.core.utils.StringTool;
import com.sprouting.metadata.view.interfaces.DocumentGenerationInterface;
import com.sprouting.metadata.view.interfaces.ViewConstant;
import com.sprouting.metadata.view.service.documentImpl.WordDocumentGenerationInterface;
import com.sprouting.metadata.view.enums.DocumentTypeEnum;
import com.sprouting.metadata.view.model.ViewConfig;
import com.sprouting.metadata.view.service.documentImpl.HtmlDocumentGenerationInterface;
import com.sprouting.metadata.view.service.documentImpl.MdDocumentGenerationInterface;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

import java.io.File;
import java.util.*;

/**
 * 文档生成过程
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/4/25 16:08
 */
public class DocumentGenerationProcess {

    /**
     * freemarker 配置实例化
     * 不需要重复创建 Configuration 实例； 它的代价很高，尤其是会丢失缓存
     */
    private final static Configuration CONFIGURATION = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);


    /**
     * 核心文档生成方法
     * @param viewConfig 配置类，可为空，则使用默认实现
     * @param tableModelList 查询出的数据
     * @throws Exception
     * @return 最终生成的文件
     */
    public File coreHandle(ViewConfig viewConfig, List<TableModel> tableModelList) throws Exception {
        // 1、初始化freemarker模板
        init();

        // 2、补全配置文件
        viewConfig = getViewConfig(viewConfig);

        // 3、选择生成的逻辑
        DocumentGenerationInterface documentGenerationInterface = selectImpl(viewConfig);

        // 文件最终保存位置
        String fileNamePath = getFileNamePath(viewConfig);
        // 模板位置
        Template template = CONFIGURATION.getTemplate(viewConfig.getDocumentTypeEnum().getFileName());
        // 生成文件的位置
        File touch = FileTool.touch(new File(fileNamePath));

        Map<String, Object> map = new HashMap<>();
        map.put("tableModelList", tableModelList);
        map.put("describe", viewConfig.getDescribe());
        map.put("version", viewConfig.getVersion());
        map.put("title", viewConfig.getTitle());

        documentGenerationInterface.produce(map, touch, template);

        return touch;
    }

    /**
     * 将文件名称以及路径传递出来
     * @param viewConfig 配置文件
     * @return
     */
    private String getFileNamePath(ViewConfig viewConfig){
        String path = viewConfig.getPath();
        if (path.endsWith("/") || path.endsWith("\\")){
            // 无问题
        } else {
            path = path + "/";
        }

        return path + viewConfig.getFileName() + "-" + viewConfig.getVersion() + viewConfig.getDocumentTypeEnum().getSuffix();
    }

    /**
     * 选择实现的方式-文档生成实现方式
     * @param viewConfig 配置文件
     * @return
     */
    private DocumentGenerationInterface selectImpl(ViewConfig viewConfig){
        switch (viewConfig.getDocumentTypeEnum()) {
            case HTML:
                return new HtmlDocumentGenerationInterface();
            case MD:
                return new MdDocumentGenerationInterface();
            case WORD:
                return new WordDocumentGenerationInterface();
            default:
                return new WordDocumentGenerationInterface();
        }
    }

    /**
     * 获取数据展示的配置
     * @param viewConfig 表生成的逻辑
     * @return
     */
    private ViewConfig getViewConfig(ViewConfig viewConfig){
        if (viewConfig == null){
            viewConfig = new ViewConfig();
        }

        if (StringTool.isEmpty(viewConfig.getFileName())){
            viewConfig.setFileName(UUID.randomUUID().toString().replace("-", ""));
        }
        if (StringTool.isEmpty(viewConfig.getPath())){
            viewConfig.setPath(ViewConstant.Base.TEMP_PATH);
        }
        if (viewConfig.getDocumentTypeEnum() == null){
            viewConfig.setDocumentTypeEnum(DocumentTypeEnum.WORD);
        }

        return viewConfig;
    }

    /**
     * 初始化freemarker模板
     */
    private void init(){
        // 设置模板加载路径
        // configuration.setDirectoryForTemplateLoading("/template/freemarker/");
        CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/template/freemarker/"));
        // 编码
        CONFIGURATION.setDefaultEncoding(ViewConstant.Base.DEFAULT_ENCODING);
        // 国际化
        CONFIGURATION.setLocale(new Locale(ViewConstant.Base.DEFAULT_LOCALE));
        // 出现异常如何处理
        CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
    }

}
